using System;
using System.ComponentModel;
using System.Runtime.CompilerServices;
using System.Threading;
using ns1;

namespace Hardcodet.Wpf.TaskbarNotification.Interop
{
	/// <summary>
	/// Receives messages from the taskbar icon through
	/// window messages of an underlying helper window.
	/// </summary>
	public class WindowMessageSink : IDisposable
	{
		/// <summary>
		/// The ID of messages that are received from the the
		/// taskbar icon.
		/// </summary>
		public const int CallbackMessageId = 1024;

		private uint uint_0;

		private bool bool_0;

		private WindowProcedureHandler windowProcedureHandler_0;

		[CompilerGenerated]
		private string string_0;

		[CompilerGenerated]
		private IntPtr intptr_0;

		[CompilerGenerated]
		private NotifyIconVersion notifyIconVersion_0;

		[CompilerGenerated]
		private Action<bool> action_0;

		[CompilerGenerated]
		private Action<MouseEvent> action_1;

		[CompilerGenerated]
		private Action<bool> action_2;

		[CompilerGenerated]
		private Action action_3;

		[CompilerGenerated]
		private bool bool_1;

		internal string String_0
		{
			[CompilerGenerated]
			get
			{
				return string_0;
			}
			[CompilerGenerated]
			private set
			{
				string_0 = value;
			}
		}

		internal IntPtr IntPtr_0
		{
			[CompilerGenerated]
			get
			{
				return intptr_0;
			}
			[CompilerGenerated]
			private set
			{
				intptr_0 = value;
			}
		}

		/// <summary>
		/// The version of the underlying icon. Defines how
		/// incoming messages are interpreted.
		/// </summary>
		public NotifyIconVersion Version
		{
			[CompilerGenerated]
			get
			{
				return notifyIconVersion_0;
			}
			[CompilerGenerated]
			set
			{
				notifyIconVersion_0 = value;
			}
		}

		/// <summary>
		/// Set to true as soon as <see cref="M:Hardcodet.Wpf.TaskbarNotification.Interop.WindowMessageSink.Dispose" />
		/// has been invoked.
		/// </summary>
		public bool IsDisposed
		{
			[CompilerGenerated]
			get
			{
				return bool_1;
			}
			[CompilerGenerated]
			private set
			{
				bool_1 = value;
			}
		}

		/// <summary>
		/// The custom tooltip should be closed or hidden.
		/// </summary>
		public event Action<bool> ChangeToolTipStateRequest
		{
			[CompilerGenerated]
			add
			{
				Action<bool> action = action_0;
				Action<bool> action2;
				do
				{
					action2 = action;
					Action<bool> value2 = (Action<bool>)Delegate.Combine(action2, value);
					action = Interlocked.CompareExchange(ref action_0, value2, action2);
				}
				while ((object)action != action2);
			}
			[CompilerGenerated]
			remove
			{
				Action<bool> action = action_0;
				Action<bool> action2;
				do
				{
					action2 = action;
					Action<bool> value2 = (Action<bool>)Delegate.Remove(action2, value);
					action = Interlocked.CompareExchange(ref action_0, value2, action2);
				}
				while ((object)action != action2);
			}
		}

		/// <summary>
		/// Fired in case the user clicked or moved within
		/// the taskbar icon area.
		/// </summary>
		public event Action<MouseEvent> MouseEventReceived
		{
			[CompilerGenerated]
			add
			{
				Action<MouseEvent> action = action_1;
				Action<MouseEvent> action2;
				do
				{
					action2 = action;
					Action<MouseEvent> value2 = (Action<MouseEvent>)Delegate.Combine(action2, value);
					action = Interlocked.CompareExchange(ref action_1, value2, action2);
				}
				while ((object)action != action2);
			}
			[CompilerGenerated]
			remove
			{
				Action<MouseEvent> action = action_1;
				Action<MouseEvent> action2;
				do
				{
					action2 = action;
					Action<MouseEvent> value2 = (Action<MouseEvent>)Delegate.Remove(action2, value);
					action = Interlocked.CompareExchange(ref action_1, value2, action2);
				}
				while ((object)action != action2);
			}
		}

		/// <summary>
		/// Fired if a balloon ToolTip was either displayed
		/// or closed (indicated by the boolean flag).
		/// </summary>
		public event Action<bool> BallonToolTipChanged
		{
			[CompilerGenerated]
			add
			{
				Action<bool> action = action_2;
				Action<bool> action2;
				do
				{
					action2 = action;
					Action<bool> value2 = (Action<bool>)Delegate.Combine(action2, value);
					action = Interlocked.CompareExchange(ref action_2, value2, action2);
				}
				while ((object)action != action2);
			}
			[CompilerGenerated]
			remove
			{
				Action<bool> action = action_2;
				Action<bool> action2;
				do
				{
					action2 = action;
					Action<bool> value2 = (Action<bool>)Delegate.Remove(action2, value);
					action = Interlocked.CompareExchange(ref action_2, value2, action2);
				}
				while ((object)action != action2);
			}
		}

		/// <summary>
		/// Fired if the taskbar was created or restarted. Requires the taskbar
		/// icon to be reset.
		/// </summary>
		public event Action TaskbarCreated
		{
			[CompilerGenerated]
			add
			{
				Action action = action_3;
				Action action2;
				do
				{
					action2 = action;
					Action value2 = (Action)Delegate.Combine(action2, value);
					action = Interlocked.CompareExchange(ref action_3, value2, action2);
				}
				while ((object)action != action2);
			}
			[CompilerGenerated]
			remove
			{
				Action action = action_3;
				Action action2;
				do
				{
					action2 = action;
					Action value2 = (Action)Delegate.Remove(action2, value);
					action = Interlocked.CompareExchange(ref action_3, value2, action2);
				}
				while ((object)action != action2);
			}
		}

		/// <summary>
		/// Creates a new message sink that receives message from
		/// a given taskbar icon.
		/// </summary>
		/// <param name="version"></param>
		public WindowMessageSink(NotifyIconVersion version)
		{
			Version = version;
			method_0();
		}

		private WindowMessageSink()
		{
		}

		internal static WindowMessageSink smethod_0()
		{
			return new WindowMessageSink
			{
				IntPtr_0 = IntPtr.Zero,
				Version = NotifyIconVersion.Vista
			};
		}

		private void method_0()
		{
			String_0 = "WPFTaskbarIcon_" + DateTime.Now.Ticks;
			windowProcedureHandler_0 = method_1;
			WindowClass windowClass_ = default(WindowClass);
			windowClass_.style = 0u;
			windowClass_.lpfnWndProc = windowProcedureHandler_0;
			windowClass_.cbClsExtra = 0;
			windowClass_.cbWndExtra = 0;
			windowClass_.hInstance = IntPtr.Zero;
			windowClass_.hIcon = IntPtr.Zero;
			windowClass_.hCursor = IntPtr.Zero;
			windowClass_.hbrBackground = IntPtr.Zero;
			windowClass_.lpszMenuName = "";
			windowClass_.lpszClassName = String_0;
			Class5.RegisterClassW(ref windowClass_);
			uint_0 = Class5.RegisterWindowMessageW("TaskbarCreated");
			IntPtr_0 = Class5.CreateWindowExW(0, String_0, "", 0, 0, 0, 1, 1, 0u, 0, 0, 0);
			if (IntPtr_0 == IntPtr.Zero)
			{
				throw new Win32Exception();
			}
		}

		private long method_1(IntPtr intptr_1, uint uint_1, uint uint_2, uint uint_3)
		{
			if (uint_1 == uint_0)
			{
				action_3();
			}
			method_2(uint_1, uint_2, uint_3);
			return Class5.DefWindowProc(intptr_1, uint_1, uint_2, uint_3);
		}

		private void method_2(uint uint_1, uint uint_2, uint uint_3)
		{
			if (uint_1 != 1024)
			{
				return;
			}
			switch (uint_3)
			{
			case 1026u:
				action_2(obj: true);
				break;
			case 1027u:
			case 1028u:
				action_2(obj: false);
				break;
			case 1029u:
				action_1(MouseEvent.BalloonToolTipClicked);
				break;
			case 1030u:
				action_0(obj: true);
				break;
			case 1031u:
				action_0(obj: false);
				break;
			case 512u:
				action_1(MouseEvent.MouseMove);
				break;
			case 513u:
				action_1(MouseEvent.IconLeftMouseDown);
				break;
			case 514u:
				if (!bool_0)
				{
					action_1(MouseEvent.IconLeftMouseUp);
				}
				bool_0 = false;
				break;
			case 515u:
				bool_0 = true;
				action_1(MouseEvent.IconDoubleClick);
				break;
			case 516u:
				action_1(MouseEvent.IconRightMouseDown);
				break;
			case 517u:
				action_1(MouseEvent.IconRightMouseUp);
				break;
			case 519u:
				action_1(MouseEvent.IconMiddleMouseDown);
				break;
			case 520u:
				action_1(MouseEvent.IconMiddleMouseUp);
				break;
			}
		}

		/// <summary>
		/// Disposes the object.
		/// </summary>
		/// <remarks>This method is not virtual by design. Derived classes
		/// should override <see cref="M:Hardcodet.Wpf.TaskbarNotification.Interop.WindowMessageSink.Dispose(System.Boolean)" />.
		/// </remarks>
		public void Dispose()
		{
			method_3(bool_2: true);
			GC.SuppressFinalize(this);
		}

		/// <summary>
		/// This destructor will run only if the <see cref="M:Hardcodet.Wpf.TaskbarNotification.Interop.WindowMessageSink.Dispose" />
		/// method does not get called. This gives this base class the
		/// opportunity to finalize.
		/// <para>
		/// Important: Do not provide destructors in types derived from
		/// this class.
		/// </para>
		/// </summary>
		~WindowMessageSink()
		{
			method_3(bool_2: false);
		}

		private void method_3(bool bool_2)
		{
			if (!IsDisposed && bool_2)
			{
				IsDisposed = true;
				Class5.DestroyWindow(IntPtr_0);
				windowProcedureHandler_0 = null;
			}
		}
	}
}
